package com.iteaj.iot.test.modbus.dtu;

import com.iteaj.iot.modbus.ModbusTcpHeader;
import com.iteaj.iot.modbus.Payload;
import com.iteaj.iot.modbus.consts.ModbusBitStatus;
import com.iteaj.iot.modbus.consts.ModbusCoilStatus;
import com.iteaj.iot.modbus.server.dtu.ModbusTcpForDtuCommonProtocol;
import com.iteaj.iot.modbus.server.dtu.ModbusTcpForDtuDecodeComponent;
import com.iteaj.iot.server.ServerProtocolHandle;
import com.iteaj.iot.server.dtu.DtuDeviceSnProtocol;
import com.iteaj.iot.test.TestConst;
import com.iteaj.iot.utils.ByteUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class ModbusDtuTestHandle implements ServerProtocolHandle<DtuDeviceSnProtocol> {

    @Autowired
    private ModbusTcpForDtuDecodeComponent component;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public Object handle(DtuDeviceSnProtocol deviceSnProtocol) {
        String equipCode = deviceSnProtocol.getEquipCode();
        System.out.println("-------------------------------------- modbus tcp for dtu 测试 ----------------------------------------------");
        //测试读写单个线圈
        ModbusCoilStatus write05 = ModbusCoilStatus.ON;
        ModbusTcpForDtuCommonProtocol.buildWrite05(equipCode, 1, 18, ModbusCoilStatus.ON).request();
        ModbusTcpForDtuCommonProtocol.buildRead01(equipCode, 1, 18, 1).request(protocol -> {
            ModbusTcpForDtuCommonProtocol commonProtocol = (ModbusTcpForDtuCommonProtocol) protocol;
            ModbusBitStatus modbusBitStatus = commonProtocol.getPayload().readStatus(0);

            boolean status = (write05 == ModbusCoilStatus.ON && modbusBitStatus == ModbusBitStatus.ON)
                    || (write05 == ModbusCoilStatus.OFF && modbusBitStatus == ModbusBitStatus.OFF);

            ModbusTcpHeader head = commonProtocol.requestMessage().getHead();
            logger.info(TestConst.LOGGER_MODBUS_DESC, component.getName()
                    , "Write05", head.getEquipCode(), head.getMessageId()
                    , status ? "通过" : "失败");
            return null;
        });

        // 测试读写多个线圈
        byte[] write0f = new byte[] {(byte) 0xFF};
        ModbusTcpForDtuCommonProtocol.buildWrite0F(equipCode, 1, 20, write0f).request();
        ModbusTcpForDtuCommonProtocol.buildRead01(equipCode, 1, 20, 8).request(protocol -> {
            ModbusTcpForDtuCommonProtocol commonProtocol = (ModbusTcpForDtuCommonProtocol) protocol;
            Payload payload = commonProtocol.getPayload();
            ModbusTcpHeader head = commonProtocol.requestMessage().getHead();
            logger.info(TestConst.LOGGER_MODBUS_DESC, component.getName()
                    , "Write0F", head.getEquipCode(), head.getMessageId()
                    , write0f[0] == payload.getPayload()[0] ? "通过" : "失败");
            return null;
        });

        // 写单个寄存器测试
        short write06 = 127;
        ModbusTcpForDtuCommonProtocol.buildWrite06(equipCode, 1, 18, ByteUtil.getBytesOfReverse(write06)).request();
        ModbusTcpForDtuCommonProtocol.buildRead03(equipCode, 1, 18, 1).request(protocol -> {
            ModbusTcpForDtuCommonProtocol commonProtocol = (ModbusTcpForDtuCommonProtocol) protocol;
            ModbusTcpHeader head = commonProtocol.requestMessage().getHead();
            short i = commonProtocol.getPayload().readShort(18);
            logger.info(TestConst.LOGGER_MODBUS_DESC, component.getName()
                    , "Write06", head.getEquipCode(), head.getMessageId()
                    , i == write06 ? "通过" : "失败");
            return null;
        });

        // 写多个寄存器测试
        int write10 = Integer.MAX_VALUE;
        ModbusTcpForDtuCommonProtocol.buildWrite10(equipCode, 1, 20, 2, ByteUtil.getBytesOfReverse(write10)).request();
        ModbusTcpForDtuCommonProtocol.buildRead03(equipCode, 1, 20, 2).request(protocol -> {
            ModbusTcpForDtuCommonProtocol commonProtocol = (ModbusTcpForDtuCommonProtocol) protocol;
            ModbusTcpHeader head = commonProtocol.requestMessage().getHead();
            int i = commonProtocol.getPayload().readInt(20);
            logger.info(TestConst.LOGGER_MODBUS_DESC, component.getName()
                    , "Write10", head.getEquipCode(), head.getMessageId()
                    , i == write10 ? "通过" : "失败");
            return null;
        });

        return null;
    }
}
